# -*- coding: utf-8 -*-

import unittest
import ahocorasick
from quality_inspections import (
    search_by_solr,
    get_metas,
    fetch_prequality_dataset
)
from decorators import time_analyze


class AhocorasickTest(unittest.TestCase):
    """
    测试有限自动机算法
    https://github.com/WojciechMula/pyahocorasick/#examples
    """

    @time_analyze
    def _init_automaton(self):
        self.automaton = ahocorasick.Automaton()
        for i, keyword in enumerate(self.keywords):
            self.automaton.add_word(keyword, (i, keyword))

        self.automaton.make_automaton()

    def _init_keywords(self):
        self.keywords = [
            "转入", "挺", "行", "小时", "输入", "互联", "稍等一下", "银", "柜台", "自动",
            "自助", "几点", "致电", "办法", "这张", "开户行", "五万", "汇款", "名下", "信用",
            "二月", "一期", "上午", "过程", "情况", "卡号", "下到", "网点", "手机", "中心",
            "录", "咨询", "不用", "升到", "分解", "转出去", "您好", "理解", "点击", "声张",
            "设备", "如果说", "两年", "钱", "免费", "这家", "明白", "带上", "尝试", "提交",
            "飞天", "他会", "大额", "工作日", "审批", "等待", "久等", "客气", "语音", "办",
            "过后", "两只", "同声", "问", "好好", "号", "手续费", "张", "确认", "本来",
            "早上", "填写", "卡", "转账", "本行", "提示", "本次", "刚刚", "民生", "有个",
            "中", "收到", "之家", "两张", "三万", "评价", "身份证件", "户有", "那种", "单位",
            "页面", "拒绝", "十一点", "带卡", "麻烦", "查询", "手动", "请", "说", "或者说",
            "先", "账户", "意见", "开", "方式", "实时", "没事", "营业厅", "这样的话", "仲裁",
            "郭先生", "能转", "设定", "显示", "核实", "两千", "做出", "两万", "只能", "哪种",
            "每期", "房产", "为您服务", "银行卡", "感谢", "激进", "人网", "atm", "最佳",
            "七百", "通", "第二个", "建议您", "跨行", "汇报", "单独", "听", "稍后", "这笔",
            "挂失", "银行", "安装", "六五", "右上角", "超出", "金卡", "完", "办事", "有没有",
            "系统", "还给", "几张", "两个", "倒", "同名", "那想", "一个二十", "欠款", "工作",
            "接收", "来电", "轻财", "银联", "忘记", "包括", "供", "确实", "超过", "任何一方",
            "开往", "一般来讲", "渠道", "网银", "这块", "资料", "是因为", "业务", "样子",
            "选择", "提醒", "保到", "人工", "电脑", "同意", "进到", "罪案", "一段时间", "见过",
            "写", "再试一下", "称呼", "电话", "服务", "感谢您", "再见", "到程", "讲", "注册",
            "成功失败", "功能", "记录", "推进", "一般来说", "地区", "at", "首期", "账", "宜",
            "信息", "行名", "开通", "查看", "转出", "失败", "申请", "卡片", "时", "原因", "点",
            "中国", "追加", "这钱", "行号", "七十四", "没关系", "同一个", "下载", "一半",
            "支付", "交易", "留", "幺", "保存", "最终", "操作", "一张", "牲畜", "需", "寄",
            "同银", "好友", "工号", "上报", "耐心", "英超", "做", "请问", "计算机", "兴趣",
            "七三出", "成功", "客户端", "周六", "转", "时间", "女士", "想", "半个", "精选", "帮",
            "何先生", "路易", "下班", "抱歉", "帐号", "转过", "账单", "行市", "试一下", "签约"]

    def _init_context(self):
        self.context = """
            您好高兴为您服务请讲。;卡明白你没事那想请问下是郭先生请问您呢。;您是网银互联需要都方式当时设定的时候就是最高只能转五万的。;这个不是您确定是只要做方式它本来就这样子的如果您超过还给您选择大额实时支付。;对完以后您最多只能转五万。;对三万好好这边可以几点下班的开户行查询到开往过后他会自动显示出来的。;那这边要提醒下到时就可以到账时间是半个小时到工作，一个工作日您只还但我不要忘记审批。;对的确实是要填写时间的。;嗯好的那请问下您是还需要别的帮助吗？;请问下，您看需要给的帮助吗？;像麻烦您在语音中做的服务进行评价可以吗？;嗯感谢来电再见。;您好高兴为您服务请讲。;卡明白你没事那想请问下是郭先生请问您呢。;您是网银互联需要都方式当时设定的时候就是最高只能转五万的。;这个不是您确定是只要做方式它本来就这样子的如果您超过还给您选择大额实时支付。;对完以后您最多只能转五万。;对三万好好这边可以几点下班的开户行查询到开往过后他会自动显示出来的。;那这边要提醒下到时就可以到账时间是半个小时到工作，一个工作日您只还但我不要忘记审批。;对的确实是要填写时间的。;嗯好的那请问下您是还需要别的帮助吗？;请问下，您看需要给的帮助吗？;像麻烦您在语音中做的服务进行评价可以吗？;嗯感谢来电再见。;
            您好很高兴为您服务。;嗯，;啊您是银行很抱歉了我这边没有办法问您核实到的，您这边如果以您有这个个人网银的话您可以这个人网银上面核实到到程女士。;应该是的话我就信用有这个功能了。;那;幺;您是说同名转账对吗？;您是通过电话银行操作转账对吗女士;请您稍等一下呢先帮您核实那麻烦问一下，您名下这两张卡都是同一个开户行吗还是在同都是同一个地区进到你的。;同一个就有;啊是这样的女士帮您看到帮您查看一下如果您通过电话银行这边，进行这个，嗯电话汇款同声本行手续费是免费的。;嗯这边的话您，嗯一般来说的话都是可以马上今天到账的但是也要看这边系统清楚，进行处理的有的时候可能是需要等待一段时间的。;这个没有办法呢一般来说的话，都是可以实时到账的。;嗯那;需要每期转账来说是实时到账的银联的系统是实时到账的女士，但是您如果然后通过这钱你激进房产，今天转账的话这个的话是需要，啊就是那个，嗯我明白好友;嗯我明白您意思您的转出卡转入卡以及说时候呢转账直接设备都开通了一天转账功能的，刚刚当中有任何一方没有开通您这边没有办法而且转账成功的。;这边的话是需要都开通的。;您是通过这个网银申请对吗？;网银申请的话您您需要的两张卡片您都是可以追加进去的，而且您可以通过这个网银操作这个同意转账的。;嗯那你;嗯女士您好那麻烦问一下您名下两张卡有没有这张上去呢。;钱信用开，;您是可以把您之后开通卡片追加上去呢女士。;您直接就是超出我这个五，您是，您直接进入之后我的账户我们声张户有一个。;有一个挂失有一个这家七三出账户您这张上去就可以了。;那请您稍等一下我帮您核实一下好吗？;女士您好请稍等一下，;您这边是想通过什么渠道操作您如果有网银的话您本人名下的两张卡片您是可以进行，这个同银转账的。;嗯好做女士您是可以操作这个手机银行转账的。;嗯是到手机上面下载一个客户端也是可以超过我，;这个两个都是用分解轻财通的，;您的账户里面您是可以看到两张卡的信息都是可以看到对吗;那请您稍等一下保险帮您何先生，;女士您好，很抱歉让您久等了是这样子的您这边的话您您是那卡片都是需要单独进行开通的，您这边在开通这个atm转账功能的时候，都会提示您这个您钱您的卡号的。;是这样的女士账户兴趣七十四中国这个电话汇款是不同意业务的;那是这样的女士我今天早上您这个意见跨行转账。;这边您开通的话都会让您选择您名下的这个卡号的。;没有刚，;是是这样子一期我们转账签约这边的话会有这个卡号可以供您精选多的您追加上去的这个卡号都是可以选择的那您看一下您这边转账的话，您这边;是这样的女士您这边的话您可以再进行。;出去;没有留一个二十不用追加直接点击atm转账这边会显示一个签约两万。;转账。;是不是点，;是的女士。;女士您好是这样的您刚才说您能看到这个信息您是可以追加上去的您没有那个就是已经罪案上去了您的卡片两张推进您都可以看得到吗？;是这样的女士您就到我的账户里面您能看到您的名下几张卡的信息呢两只，;看到的话就大两年都是之家上去的，您这边飞天咱们转账的话是因为帐号，首先只是后面有个相当的一个欠款您是可以选择的。;嗯是的女士。;那您这样子好吗女士您到您名下有另外一张卡片通过民生账户做了一个挂失最佳计算机账户您再追加一次好吗？;对他然后再尝试操作;那就升到是吗女士那，用请您这边的话您可以把您的网银牲畜出来您稍后再重新行市操作一下的，;我寄;呢是上报是你说要;因为是这样的女士那我建议您这边的话可以本人带上您这个有保到柜台网点去。;您这个at零这个;转账功能柜台网点也都是可以帮您开通的。;营业厅;那确实很抱歉了女士您这边的话我也不知道您电脑页面是什么显示的;但是一半我们再进行操作的时候这个后面您这家是不是卡片您都是可以进行选择到这边也不知道您电脑上面是不是安装什么其他的两千这边没有办法问您核实这个只能建议您本人，可以带您本人的卡片已经有这个身份证件，到柜台网点去到您名下两张卡片的，这个，嗯就是。;atm转账功能包括电话银行转账功能您这边都是可以听，包括电话银行汇款功能您都是可以进行开通一下的女士。;你;您这边，这边确实资料显示是要进行单独开通的这边的话您的网银如果没有办法进行过您选择银行卡号的话那很抱歉呢就是用您本人带卡和有效的身份证件，到柜台网点去分别打直接卡片的业务都挺开通的。;嗯好的我的工号是三六五五一般来说您追加上去都是没有应该;嗯是这样女士您这边的话同银转账您在电话银行的二月二月英超当当中可是可以进行操作的，人工可能没有办法给您操作了;我您到您的意思那这边只是给您个提示了在自助上面可以操作同名转账的。;了。;那很抱歉了女士这边您可以本人带卡和有效身份证件到柜台网点去开通一下这个，金卡atm转账功能以及这个呃我看到了汇款功能呢确实很抱歉了女士。嗯好的不客气了那麻烦您在稍后您当中本次。;您好很高兴为您服务。;嗯，;啊您是银行很抱歉了我这边没有办法问您核实到的，您这边如果以您有这个个人网银的话您可以这个人网银上面核实到到程女士。;应该是的话我就信用有这个功能了。;那;幺;您是说同名转账对吗？;您是通过电话银行操作转账对吗女士;请您稍等一下呢先帮您核实那麻烦问一下，您名下这两张卡都是同一个开户行吗还是在同都是同一个地区进到你的。;同一个就有;啊是这样的女士帮您看到帮您查看一下如果您通过电话银行这边，进行这个，嗯电话汇款同声本行手续费是免费的。;嗯这边的话您，嗯一般来说的话都是可以马上今天到账的但是也要看这边系统清楚，进行处理的有的时候可能是需要等待一段时间的。;这个没有办法呢一般来说的话，都是可以实时到账的。;嗯那;需要每期转账来说是实时到账的银联的系统是实时到账的女士，但是您如果然后通过这钱你激进房产，今天转账的话这个的话是需要，啊就是那个，嗯我明白好友;嗯我明白您意思您的转出卡转入卡以及说时候呢转账直接设备都开通了一天转账功能的，刚刚当中有任何一方没有开通您这边没有办法而且转账成功的。;这边的话是需要都开通的。;您是通过这个网银申请对吗？;网银申请的话您您需要的两张卡片您都是可以追加进去的，而且您可以通过这个网银操作这个同意转账的。;嗯那你;嗯女士您好那麻烦问一下您名下两张卡有没有这张上去呢。;钱信用开，;您是可以把您之后开通卡片追加上去呢女士。;您直接就是超出我这个五，您是，您直接进入之后我的账户我们声张户有一个。;有一个挂失有一个这家七三出账户您这张上去就可以了。;那请您稍等一下我帮您核实一下好吗？;女士您好请稍等一下，;您这边是想通过什么渠道操作您如果有网银的话您本人名下的两张卡片您是可以进行，这个同银转账的。;嗯好做女士您是可以操作这个手机银行转账的。;嗯是到手机上面下载一个客户端也是可以超过我，;这个两个都是用分解轻财通的，;您的账户里面您是可以看到两张卡的信息都是可以看到对吗;那请您稍等一下保险帮您何先生，;女士您好，很抱歉让您久等了是这样子的您这边的话您您是那卡片都是需要单独进行开通的，您这边在开通这个atm转账功能的时候，都会提示您这个您钱您的卡号的。;是这样的女士账户兴趣七十四中国这个电话汇款是不同意业务的;那是这样的女士我今天早上您这个意见跨行转账。;这边您开通的话都会让您选择您名下的这个卡号的。;没有刚，;是是这样子一期我们转账签约这边的话会有这个卡号可以供您精选多的您追加上去的这个卡号都是可以选择的那您看一下您这边转账的话，您这边;是这样的女士您这边的话您可以再进行。;出去;没有留一个二十不用追加直接点击atm转账这边会显示一个签约两万。;转账。;是不是点，;是的女士。;女士您好是这样的您刚才说您能看到这个信息您是可以追加上去的您没有那个就是已经罪案上去了您的卡片两张推进您都可以看得到吗？;是这样的女士您就到我的账户里面您能看到您的名下几张卡的信息呢两只，;看到的话就大两年都是之家上去的，您这边飞天咱们转账的话是因为帐号，首先只是后面有个相当的一个欠款您是可以选择的。;嗯是的女士。;那您这样子好吗女士您到您名下有另外一张卡片通过民生账户做了一个挂失最佳计算机账户您再追加一次好吗？;对他然后再尝试操作;那就升到是吗女士那，用请您这边的话您可以把您的网银牲畜出来您稍后再重新行市操作一下的，;我寄;呢是上报是你说要;因为是这样的女士那我建议您这边的话可以本人带上您这个有保到柜台网点去。;您这个at零这个;转账功能柜台网点也都是可以帮您开通的。;营业厅;那确实很抱歉了女士您这边的话我也不知道您电脑页面是什么显示的;但是一半我们再进行操作的时候这个后面您这家是不是卡片您都是可以进行选择到这边也不知道您电脑上面是不是安装什么其他的两千这边没有办法问您核实这个只能建议您本人，可以带您本人的卡片已经有这个身份证件，到柜台网点去到您名下两张卡片的，这个，嗯就是。;atm转账功能包括电话银行转账功能您这边都是可以听，包括电话银行汇款功能您都是可以进行开通一下的女士。;你;您这边，这边确实资料显示是要进行单独开通的这边的话您的网银如果没有办法进行过您选择银行卡号的话那很抱歉呢就是用您本人带卡和有效的身份证件，到柜台网点去分别打直接卡片的业务都挺开通的。;嗯好的我的工号是三六五五一般来说您追加上去都是没有应该;嗯是这样女士您这边的话同银转账您在电话银行的二月二月英超当当中可是可以进行操作的，人工可能没有办法给您操作了;我您到您的意思那这边只是给您个提示了在自助上面可以操作同名转账的。;了。;那很抱歉了女士这边您可以本人带卡和有效身份证件到柜台网点去开通一下这个，金卡atm转账功能以及这个呃我看到了汇款功能呢确实很抱歉了女士。嗯好的不客气了那麻烦您在稍后您当中本次。;
            再见。;您好很高兴为您服务三您好，;交易倒是;哦那如果是这个情况的话明白了请问下怎么称呼您呢是是;啊张先生那现在请您在这个页面的右上角任务中心去理解一下，;这里呢在您确认一下就是办的原因是什么。;见过之后呢在这个注册，第二个已办事宜十一点一下;然后再一般需里面您看一下能不能看到刚才是不是比较一个记录，;二交易七百他就边有一个这个拒绝失败原因的写的是什么你看一下。;啊!或者是这个现在不是很清楚您说在接收方式吧;哦，;仲裁中不正常再说行名行号这个账单就不正常。;哦那如果是这个情况的话呢。;请问一下您这个。;上午好。;那这样呃行名行号这笔钱是不是不能尝试帮您收到帮您看一下。;那感谢您的耐心等待这里帮您看了一下就是说您现在说的是一个跨行的转账是吗这块行啊那如果是跨行转账这个刚才最终的信息就是您这个输入进去了，;以前保存以前有不成功我的。;哦那如果是这个情况的话呢，您当时致电的时候提交是显示的是什么工作是吗？;嗯。;那您用的这个支付方式是那种了行吗？;啊啊!;啊您好，啊是哪种支付方式呢，;的话汇款只是说我没关系跨行汇款的就是跨行汇款的时候，选择的支付方式是那种。;啊是的。;啊那如果说是这个情况的话呢，因为您以前能转成功过并且呢就是直接选择的这个对方的信息;啊那如果是这样的话您看一下能不能重新再做一次试一下吧或者说您这次是在手动的手动的把这信息的录进去看一下，;这个，;这个是您审批没有成功失败了所以说这个钱并没有帮您转出去。;可以一个;还是的这个麻烦您在路易咨询一下因为;过程当中;是有什么问题的话呢应该是汇报首期是的并且您以前呢，嗯这个最终这个单位是有转过的。啊如果有转过的话一般来讲应该是可以，转成功了所以麻烦您可以再试一下，;哦好的。;啊不客气的那请问下您还需要其他帮助吗;好的好的麻烦您在稍后语音周六的服务做出;哎那现在来电，先生再见。;再见。;您好很高兴为您服务三您好，;交易倒是;哦那如果是这个情况的话明白了请问下怎么称呼您呢是是;啊张先生那现在请您在这个页面的右上角任务中心去理解一下，;这里呢在您确认一下就是办的原因是什么。;见过之后呢在这个注册，第二个已办事宜十一点一下;然后再一般需里面您看一下能不能看到刚才是不是比较一个记录，;二交易七百他就边有一个这个拒绝失败原因的写的是什么你看一下。;啊!或者是这个现在不是很清楚您说在接收方式吧;哦，;仲裁中不正常再说行名行号这个账单就不正常。;哦那如果是这个情况的话呢。;请问一下您这个。;上午好。;那这样呃行名行号这笔钱是不是不能尝试帮您收到帮您看一下。;那感谢您的耐心等待这里帮您看了一下就是说您现在说的是一个跨行的转账是吗这块行啊那如果是跨行转账这个刚才最终的信息就是您这个输入进去了，;以前保存以前有不成功我的。;哦那如果是这个情况的话呢，您当时致电的时候提交是显示的是什么工作是吗？;嗯。;那您用的这个支付方式是那种了行吗？;啊啊!;啊您好，啊是哪种支付方式呢，;的话汇款只是说我没关系跨行汇款的就是跨行汇款的时候，选择的支付方式是那种。;啊是的。;啊那如果说是这个情况的话呢，因为您以前能转成功过并且呢就是直接选择的这个对方的信息;啊那如果是这样的话您看一下能不能重新再做一次试一下吧或者说您这次是在手动的手动的把这信息的录进去看一下，;这个，;这个是您审批没有成功失败了所以说这个钱并没有帮您转出去。;可以一个;还是的这个麻烦您在路易咨询一下因为;过程当中;是有什么问题的话呢应该是汇报首期是的并且您以前呢，嗯这个最终这个单位是有转过的。啊如果有转过的话一般来讲应该是可以，转成功了所以麻烦您可以再试一下，;哦好的。;啊不客气的那请问下您还需要其他帮助吗;好的好的麻烦您在稍后语音周六的服务做出;哎那现在来电，先生再见。;
        """

    def setUp(self):
        self._init_context()
        self._init_keywords()
        self._init_automaton()

    @time_analyze
    def test_ahocorasick(self):
        """
        >>> haystack = '_hershe_'
        >>> for idx, key in enumerate('he her hers she'.split()):
        ...   A.add_word(key, (idx, key))
        ...
        >>> A.make_automaton()

        >>> for end, (insert_order, kw) in A.iter(haystack):
        ...     start = end - len(kw) + 1
        ...     print((start, end, (insert_order, kw)))
        ...     assert haystack[start:start + len(kw)] == kw
        ...
        (1, 2, (0, 'he'))
        (1, 3, (1, 'her'))
        (1, 4, (2, 'hers'))
        (4, 6, (3, 'she'))
        (5, 6, (0, 'he'))
        """
        for end, (_, keyword) in self.automaton.iter(self.context):
            keyword_len = len(keyword)
            start = end - keyword_len + 1
            # print("{}, {}".format(start, keyword))
            self.assertEqual(
                self.context[start:start + keyword_len], keyword)

    def test_another_ahocorasick(self):
        self.keywords = ["天安门", "地安门", "广场", "场", "爱", "我", "天安门"]
        self.context = "我爱北京天安门广场。"
        self.automaton = ahocorasick.Automaton()
        for i, keyword in enumerate(self.keywords):
            self.automaton.add_word(keyword, (i, keyword))

        self.automaton.make_automaton()

        result = {}
        for end, (i, kw) in self.automaton.iter(self.context):
            start = end - len(kw) + 1
            result[kw] = (start, end)

        self.assertEqual(result["我"], (0, 0))
        self.assertEqual(result["爱"], (1, 1))
        self.assertEqual(result["天安门"], (4, 6))
        self.assertEqual(result["广场"], (7, 8))
        self.assertTrue("地安门" not in result.keys())


class QualityInspectionsTest(unittest.TestCase):

    def setUp(self):
        self.solr_condtition = "start_time: {} AND area_of_job: {}".format(
            "[1427472000000 TO 1427558399000]", "dy-gz")
        self.ids = ["dy-gz-t75474539_20150328_6353815.mp3"]

    @time_analyze
    def test_function_search_by_solr(self):
        """ 测试 search_by_solr 方法 """
        docs = list(search_by_solr(self.solr_condtition))

        self.assertTrue(len(docs) != 0)
        self.assertTrue("id" not in docs[0])

    @time_analyze
    def test_function_get_metas(self):
        """ 测试 get_metas 方法 """
        metas = list(get_metas(self.ids))

        self.assertEqual(len(metas), 1)
        self.assertTrue(b"cf:callnumber" in metas[0])
        self.assertTrue(b"cf:filename" in metas[0])
        self.assertTrue(b"cf:plaintextb" in metas[0])

    @time_analyze
    def test_function_get_metas_only_callnumber(self):
        """ hbase 只获取 callnumber """
        metas_of_callnumber = list(
            get_metas(self.ids, columns=("cf:callnumber",)))

        self.assertEqual(len(metas_of_callnumber), 1)
        self.assertTrue(b"cf:callnumber" in metas_of_callnumber[0])
        self.assertTrue(b"cf:filename" not in metas_of_callnumber[0])
        self.assertTrue(b"cf:plaintextb" not in metas_of_callnumber[0])

    @time_analyze
    def test_function_fetch_prequality_dataset(self):
        """ 测试 fetch_prequality_dataset 方法 """
        data_set = list(fetch_prequality_dataset(self.solr_condtition))

        self.assertTrue(len(data_set) != 0)
        self.assertTrue("id" not in data_set[0])

    @time_analyze
    def test_quality_inspection(self):
        """ 测试质检计算 """
        pass


if __name__ == "__main__":
    unittest.main()
